// axiosProxy.js
const axios = require("axios");
const { buildUpstreamHeaders } = require("../utils/header");
const Vehicle = require("../models/Vehicle");
const User = require("../models/User");
const LogModel = require("../models/Log");

// 上游基础地址
const UPSTREAM_BASE = process.env.UPSTREAM_BASE || "https://tapi.zeehoev.com";

// 需要做入库的关键接口
const LOGIN_ENDPOINTS = ["/v1.0/mine/cfmotoservermine/user/loginByPhone"];
const VEHICLE_LIST_ENDPOINTS = [
  "/v1.0/app/cfmotoserverapp/vehicleHomePage",
  "/v1.0/mine/cfmotoservermine/vehicle/homepage",
];

// 需要数据合并的接口配置
const DATA_MERGE_ENDPOINTS = {
  "/v1.0/mine/cfmotoservermine/vehicle/homepage": {
    handler: mergeVehicleHomepage,
    description: "车辆首页数据合并",
  },
  "/v1.0/app/cfmotoserverapp/vehicleHomePage": {
    handler: mergeVehicleHomepage,
    description: "车辆首页数据合并(上游APP接口)",
  },
  "/v1.0/mine/cfmotoservermine/vehicle/detail": {
    handler: mergeVehicleDetail,
    description: "车辆详情数据合并",
  },
  "/v1.0/mine/cfmotoservermine/user/info": {
    handler: mergeUserInfo,
    description: "用户信息数据合并",
  },
};

// 根据请求构造绝对 URL
function toAbsoluteUrl(p, req) {
  
  if (!p) return null;
  // 已是绝对地址
  if (/^https?:\/\//i.test(p)) return p;
  const envBase = typeof process.env.PUBLIC_BASE_URL === 'string' ? process.env.PUBLIC_BASE_URL.trim() : process.env.PUBLIC_BASE_URL;
  let base = null;
  if (typeof envBase === "string" && /^https?:\/\//i.test(envBase)) {
    base = envBase.replace(/\/$/, "");
  } else {
    const host = req?.headers?.["x-forwarded-host"] || req?.headers?.["host"] || "";
    const proto = req?.headers?.["x-forwarded-proto"] || req?.protocol || "http";
    if (host) base = `${proto}://${host}`;
  }
  const path = p.startsWith('/') ? p : `/${p}`;
  // 无法推断 base 时，回退为相对路径，避免拼接出 "undefinedxxx"
  return base ? `${base}${path}` : path;
}

// 客户端 IP 提取
function getClientIp(req) {
  const xff = req.headers["x-forwarded-for"];
  if (typeof xff === "string" && xff.length) {
    return xff.split(",")[0].trim();
  }
  return req.ip || req.connection?.remoteAddress || "";
}

// 从 Authorization 提取用户
async function extractUserFromReq(req) {
  try {
    const authHeader = req.headers?.authorization || req.headers?.Authorization;
    if (typeof authHeader !== "string") return { userId: null, phone: null };
    const m = authHeader.match(/bearer\s+(.*)/i);
    const token = m ? m[1] : null;
    if (!token) return { userId: null, phone: null };
    const user = await User.verifyToken(token);
    return { userId: user?.id || null, phone: user?.phone || null };
  } catch (_) {
    return { userId: null, phone: null };
  }
}

// 统一行为日志
async function logAction(req, action, meta = {}) {
  const { userId, phone } = await extractUserFromReq(req);
  const payload = {
    level: "INFO",
    type: "action",
    action,
    method: req.method,
    path: req.path,
    ip: getClientIp(req),
    ua: req.headers["user-agent"] || "",
    userId,
    phone,
    time: new Date().toISOString(),
    ...meta,
  };
  try {
    await LogModel.logAction({
      level: payload.level,
      type: payload.type,
      action: payload.action,
      method: payload.method,
      path: payload.path,
      ip: payload.ip,
      ua: payload.ua,
      userId: payload.userId,
      phone: payload.phone,
      time: payload.time,
      meta,
    });
  } catch (_) {
    // 持久化失败不影响主流程
  }
}
/**
 * 合并车辆首页数据
 */
async function mergeVehicleHomepage(upstreamData, req) {
  const d = upstreamData?.data;
  if (!d) return upstreamData;
  if (Array.isArray(d)) {
    const mergedArray = await Promise.all(
      d.map(async (v) => {
        const vid = v?.vehicleId || v?.vinNo || v?.deviceName || null;
        let localVehicle = null;
        if (vid) {
          try {
            localVehicle = await Vehicle.findByVehicleId(vid);
          } catch (_) {}
        }
        const customAbs = localVehicle?.custom_image
          ? toAbsoluteUrl(localVehicle.custom_image, req)
          : null;
        return {
          ...v,
          customImage: customAbs || null,
          localData: !!localVehicle,
        };
      })
    );
    return {
      ...upstreamData,
      data: mergedArray,
    };
  }
  // 兼容多种列表字段
  const listKey = Array.isArray(d?.vehicles)
    ? "vehicles"
    : Array.isArray(d?.vehicleList)
    ? "vehicleList"
    : Array.isArray(d?.list)
    ? "list"
    : null;
  if (!listKey) return upstreamData;

  const srcList = d[listKey] || [];
  const mergedVehicles = await Promise.all(
    srcList.map(async (v) => {
      const vid = v?.vehicleId || v?.vinNo || v?.deviceName || null;
      let localVehicle = null;
      if (vid) {
        try {
          localVehicle = await Vehicle.findByVehicleId(vid);
        } catch (_) {}
      }
      const customAbs = localVehicle?.custom_image
        ? toAbsoluteUrl(localVehicle.custom_image, req)
        : null;
      return {
        ...v,
        customImage: customAbs || null,
        localData: !!localVehicle,
      };
    })
  );

  return {
    ...upstreamData,
    data: {
      ...d,
      [listKey]: mergedVehicles,
      // 同时规范化为 vehicles，便于前端统一读取
      vehicles: mergedVehicles,
    },
  };
}

/**
 * 合并车辆详情数据
 */
async function mergeVehicleDetail(upstreamData, req) {
  if (!upstreamData?.data?.vehicleId) return upstreamData;

  const localVehicle = await Vehicle.findByVehicleId(
    upstreamData.data.vehicleId
  );
  const customAbs = localVehicle?.custom_image
    ? toAbsoluteUrl(localVehicle.custom_image, req)
    : null;
  return {
    ...upstreamData,
    data: {
      ...upstreamData.data,
      customImage: customAbs || localVehicle?.custom_image || null,
      localData: !!localVehicle,
    },
  };
}

/**
 * 合并用户信息数据
 */
async function mergeUserInfo(upstreamData, req) {
  if (!upstreamData?.data?.phone) return upstreamData;

  const localUser = await User.findByPhone(upstreamData.data.phone);
  return {
    ...upstreamData,
    data: {
      ...upstreamData.data,
      customAvatar: localUser?.custom_avatar || null,
      localData: !!localUser,
    },
  };
}

/**
 * 判断是否需要数据合并
 */
function needsDataMerge(path) {
  return Object.keys(DATA_MERGE_ENDPOINTS).some((endpoint) =>
    path.includes(endpoint)
  );
}

/**
 * 获取合并处理器
 */
function getDataMergeHandler(path) {
  for (const [endpoint, config] of Object.entries(DATA_MERGE_ENDPOINTS)) {
    if (path.includes(endpoint)) {
      return config.handler;
    }
  }
  return null;
}

/**
 * 通用 Axios 代理函数
 * @param {Object} req - Express request
 * @param {Object} res - Express response
 * @returns {Promise<void>}
 */
async function axiosProxy(req, res) {
  const { path } = req;
  const method = req.method.toLowerCase();
  const url = UPSTREAM_BASE + path;
  const config = {
    params: req.query,
    data: req.body,
    method,
    url,
    headers: {},
  };

  // 构建正确的上游请求头（包含签名与登录强制 Basic 等策略）
  config.headers = buildUpstreamHeaders(req);

  // 请求跟踪
  const requestId = `${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
  const startedAt = Date.now();

  try {
    const response = await axios(config);
    // console.log(response);

    let finalData = response.data;
    // 检查是否需要数据合并
    if (needsDataMerge(path)) {
      const handler = getDataMergeHandler(path);
      if (handler) {
        finalData = await handler(response.data, req);
        
      }
    }

    // 成功后做入库副作用（不影响响应）
    try {
      // 登录成功：落用户表 + 行为日志
      if (
        LOGIN_ENDPOINTS.some((p) => path.includes(p)) &&
        finalData?.code === "10000"
      ) {
        const body = req.body || {};
        const data = finalData?.data || {};
        const token = data?.tokenInfo?.access_token || null;
        const refreshToken = data?.tokenInfo?.refresh_token || null;

        if (body?.phone && token) {
          await User.upsert({
            phone: body.phone,
            username:
              body?.username ||
              body?.nickName ||
              data?.user?.userName ||
              data?.nickName ||
              body.phone,
            token,
            refresh_token: refreshToken,
            nickname: data?.nickName || data?.user?.nickName || null,
            avatar_url: data?.avatar || data?.user?.avatar || null,
            city: body?.city || null,
            province: body?.province || null,
            latitude: body?.latitude || null,
            longitude: body?.longitude || null,
          });
          console.log("✅ 用户入库/更新成功:", body.phone);
          await logAction(req, "login_success", { phone: body.phone });
        }
      }

      // 车辆列表：落车辆表（与用户关系）+ 行为日志
      if (
        VEHICLE_LIST_ENDPOINTS.some((p) => path.includes(p)) &&
        finalData?.code === "10000"
      ) {
        const data = finalData?.data || {};
        const vehicles = Array.isArray(data)
          ? data
          : data?.vehicles || data?.vehicleList || data?.list || [];

        // 从前端 Authorization 中识别用户
        const authHeader =
          req.headers?.authorization || req.headers?.Authorization;
        let token = null;
        if (typeof authHeader === "string") {
          const m = authHeader.match(/bearer\s+(.*)/i);
          token = m ? m[1] : null;
        }

        let userId = null;
        if (token) {
          const user = await User.verifyToken(token);
          userId = user?.id || null;
        }

        if (Array.isArray(vehicles) && vehicles.length) {
          for (const v of vehicles) {
            const mapped = {
              vehicle_id: v?.vehicleId || v?.vinNo || v?.deviceName || null,
              user_id: userId,
              vin: v?.vinNo || null,
              model: v?.vehicleTypeName || v?.model || null,
              brand: v?.brand || "CFMOTO",
              series: v?.vehicleType || null,
              color: v?.color || null,
              year: v?.year || null,
              mileage: v?.totalRideMile || v?.totalMileage || 0,
              battery_level: v?.bmssoc ?? v?.soc ?? null,
              charging_status: String(
                v?.chargeState ?? v?.BMSChargeState ?? ""
              ),
              location_lat: v?.location?.latitude ?? v?.latitude ?? null,
              location_lng: v?.location?.longitude ?? v?.longitude ?? null,
            };
            if (mapped.vehicle_id) {
              try {
                await Vehicle.upsert(mapped);
              } catch (e) {
                console.error("车辆入库失败", mapped.vehicle_id, e?.message);
              }
            }
          }
          console.log(`✅ 车辆入库/更新完成，共 ${vehicles.length} 条`);
          await logAction(req, "vehicle_list_success", {
            count: vehicles.length,
          });
        }
      }

      // 签到成功：记录行为
      if (
        path.includes("/v1.0/mine/cfmotoservermine/signin") &&
        req.method.toLowerCase() === "post" &&
        finalData?.code === "10000"
      ) {
        await logAction(req, "signin_success");
      }

      // 车辆详情：读取即入库（最小字段），不写 status
      if (
        path.includes("/v1.0/mine/cfmotoservermine/vehicle/detail") &&
        finalData?.code === "10000"
      ) {
        const v = finalData?.data || {};
        const mapped = {
          vehicle_id: v?.vehicleId || v?.vinNo || v?.deviceName || null,
          user_id: null,
          vin: v?.vinNo || null,
          model: v?.vehicleTypeName || v?.model || null,
          brand: v?.brand || "CFMOTO",
          series: v?.vehicleType || null,
          color: v?.color || null,
          year: v?.year || null,
          mileage: v?.totalRideMile || v?.totalMileage || 0,
          battery_level: v?.bmssoc ?? v?.soc ?? null,
          charging_status: String(v?.chargeState ?? v?.BMSChargeState ?? ""),
          location_lat: v?.location?.latitude ?? v?.latitude ?? null,
          location_lng: v?.location?.longitude ?? v?.longitude ?? null,
        };
        if (mapped.vehicle_id) {
          try {
            await Vehicle.upsert(mapped);
            console.log("✅ 车辆详情入库/更新成功:", mapped.vehicle_id);
          } catch (e) {
            console.error("车辆详情入库失败", mapped.vehicle_id, e?.message);
          }
        }
      }
    } catch (persistErr) {
      console.error("入库副作用失败（不影响响应）:", persistErr?.message);
    }

    // 记录代理成功日志（不阻塞响应）
    try {
      await LogModel.logProxy({
        request_id: requestId,
        method: req.method,
        path: req.originalUrl || req.path,
        headers: config.headers,
        body: req.body,
        response_status: response.status,
        response_body: finalData,
        duration: Date.now() - startedAt,
        error_message: null,
      });
    } catch (_) {}

    res.status(response.status).json(finalData);
  } catch (error) {
    const status = error.response?.status || 502;
    const message = error.response?.data?.message || "上游服务错误";
    console.error("代理请求失败:", error.message);

    // 记录代理失败日志（不阻塞响应）
    try {
      await LogModel.logProxy({
        request_id: requestId,
        method: req.method,
        path: req.originalUrl || req.path,
        headers: config.headers,
        body: req.body,
        response_status: status,
        response_body: error.response?.data || null,
        duration: Date.now() - startedAt,
        error_message: error.message,
      });
    } catch (_) {}

    res.status(status).json({
      code: status === 502 ? "50200" : "50000",
      message: message,
      data: null,
      timestamp: new Date().toISOString(),
    });
  }
}

module.exports = {
  axiosProxy,
  DATA_MERGE_ENDPOINTS,
};
